package com.kun.service.impl;

import com.kun.entity.JdContent;
import com.kun.service.SearchService;
import com.kun.util.JdJsoupParseUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author kun.li
 */
@Service
@Slf4j
public class SearchServiceImpl implements SearchService {


    @Autowired
    private JdJsoupParseUtil jdJsoupParseUtil;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    private final static String INDEX_NAME = "jd_search";


    @Override
    public List<JdContent> searchList(Integer page, Integer size, String keyword) {
        List<JdContent> jdContentList = new ArrayList<>();
        try {
            // 数据检索
            NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
            nativeSearchQueryBuilder.withQuery(QueryBuilders.matchQuery("name", keyword));
            // 分页
            nativeSearchQueryBuilder.withPageable(PageRequest.of(page, size));
            NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
            // 数据同步
            log.info("数据同步开始");
            List<JdContent> contents = jdJsoupParseUtil.getJdContentList(keyword);
            elasticsearchOperations.save(contents, IndexCoordinates.of(INDEX_NAME));
            log.info("数据同步结束");
            SearchHits<JdContent> searchHits = elasticsearchOperations.search(nativeSearchQuery, JdContent.class, IndexCoordinates.of(INDEX_NAME));
            for (SearchHit<JdContent> searchHit : searchHits.getSearchHits()) {
                JdContent content = searchHit.getContent();
                jdContentList.add(content);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return jdContentList;
    }

    @Override
    public Collection<String> suggestionList(String keyword) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        CompletionSuggestionBuilder completionSuggestionBuilder = SuggestBuilders.completionSuggestion("name.suggest");
        completionSuggestionBuilder.prefix(keyword).skipDuplicates(true).size(5);
        suggestBuilder.addSuggestion("my-suggestion", completionSuggestionBuilder);
        nativeSearchQueryBuilder.withSuggestBuilder(suggestBuilder);
        nativeSearchQueryBuilder.withPageable(PageRequest.of(0, 30));
        SearchHits<JdContent> search = elasticsearchOperations.search(nativeSearchQueryBuilder.build(), JdContent.class, IndexCoordinates.of(INDEX_NAME));
        Suggest suggest = search.getSuggest();
        Set<String> sugggestionList = new HashSet<>();
        if (suggest != null) {
            List<? extends Suggest.Suggestion.Entry.Option> options = suggest.getSuggestion("my-suggestion").getEntries().get(0).getOptions();
            for (Suggest.Suggestion.Entry.Option option : options) {
                String text = option.getText();
                sugggestionList.add(text);
            }
        }
        return sugggestionList;
    }


}
